package com.kmxd.ams.controller.system;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kmxd.ams.core.common.bo.LoginUser;
import com.kmxd.ams.core.common.constant.Constants;
import com.kmxd.ams.core.common.constant.ErrorCode;
import com.kmxd.ams.core.common.enums.LogLevelEnum;
import com.kmxd.ams.core.common.enums.LogTypeEnum;
import com.kmxd.ams.core.common.enums.UserPlatformEnum;
import com.kmxd.ams.core.exception.BizTipException;
import com.kmxd.ams.core.log.annotation.AutoLog;
import com.kmxd.ams.core.result.R;
import com.kmxd.ams.core.util.StpAppUtil;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.web.bind.annotation.*;

/**
 * 在线用户 前端控制器
 *
 * @author admin
 */
@Tag(name = "在线用户")
@RestController
@RequestMapping("/system/monitor/online")
public class SysUserOnlineCtl {

  /** 分页查询 */
  @GetMapping("/selectPage")
  @AutoLog(module = "在线用户", type = LogTypeEnum.SYSTEM, level = LogLevelEnum.LOW, title = "分页查询")
  public R<Page<LoginUser>> selectPage(Page reqPage, String username, String userPlatform) {
    List<LoginUser> loginUserList = new ArrayList();
    List<String> keys = StpUtil.searchTokenValue("", 0, -1, true);
    for (String key : keys) {
      // token sample, Authorization:login:token:8734da0866f4440daeea3d836d5ecf8c
      String tokenValue =
          StrUtil.subAfter(key, StpUtil.getTokenName() + ":" + StpUtil.TYPE + ":token:", true);
      LoginUser item =
          (LoginUser) StpUtil.getTokenSessionByToken(tokenValue).get(Constants.LOGIN_USER_KEY);
      if (Objects.nonNull(item)) {
        if (StrUtil.isNotBlank(username) && StrUtil.isNotBlank(userPlatform)) {
          if (StrUtil.contains(item.getUsername(), username)
              && item.getUserPlatform().equals(userPlatform)) {
            loginUserList.add(item);
          }
        } else if (StrUtil.isNotBlank(username)) {
          if (StrUtil.contains(item.getUsername(), username)) {
            loginUserList.add(item);
          }
        } else if (StrUtil.isNotBlank(userPlatform)) {
          if (item.getUserPlatform().equals(userPlatform)) {
            loginUserList.add(item);
          }
        } else {
          loginUserList.add(item);
        }
      }
    }

    List<String> keys2 = StpAppUtil.searchTokenValue("", 0, -1);
    for (String key : keys2) {
      // token sample, Authorization:login:token:8734da0866f4440daeea3d836d5ecf8c
      String tokenValue =
          StrUtil.subAfter(
              key, StpAppUtil.getTokenName() + ":" + StpAppUtil.TYPE + ":token:", true);
      LoginUser item =
          (LoginUser) StpAppUtil.getTokenSessionByToken(tokenValue).get(Constants.LOGIN_USER_KEY);
      if (Objects.nonNull(item)) {
        if (StrUtil.isNotBlank(username) && StrUtil.isNotBlank(userPlatform)) {
          if (StrUtil.contains(item.getUsername(), username)
              && item.getUserPlatform().equals(userPlatform)) {
            loginUserList.add(item);
          }
        } else if (StrUtil.isNotBlank(username)) {
          if (StrUtil.contains(item.getUsername(), username)) {
            loginUserList.add(item);
          }
        } else if (StrUtil.isNotBlank(userPlatform)) {
          if (item.getUserPlatform().equals(userPlatform)) {
            loginUserList.add(item);
          }
        } else {
          loginUserList.add(item);
        }
      }
    }

    // 进行排序，以登陆时间倒序
    loginUserList =
        loginUserList.stream()
            .sorted(Comparator.comparing(LoginUser::getLoginTime).reversed())
            .collect(Collectors.toList());

    Page<LoginUser> page =
        new Page<>(reqPage.getCurrent(), reqPage.getSize(), loginUserList.size());
    if (page.getPages() > 0) {
      int fromIndex = (int) ((page.getCurrent() - 1) * page.getSize());
      int toIndex =
          page.getCurrent() == page.getPages()
              ? (int) page.getTotal()
              : (int) (fromIndex + page.getSize());
      page.setRecords(loginUserList.subList(fromIndex, toIndex));
    }
    return R.success(page);
  }

  /** 强制退出 */
  @PostMapping("/forceLogout")
  @SaCheckPermission("monitor:online:forceLogout")
  @AutoLog(module = "在线用户", type = LogTypeEnum.SYSTEM, level = LogLevelEnum.HIGH, title = "强制退出")
  public R<Void> forceLogout(@RequestParam String userPlatform, @RequestParam String token) {
    if (Objects.equals(userPlatform, UserPlatformEnum.WEB.getCode())) {
      if (Objects.equals(StpUtil.getTokenValue(), token)) {
        throw BizTipException.instance(ErrorCode.EXCEPTION, "强制退出，不能退出当前登录用户");
      }
      StpUtil.logoutByTokenValue(token);
    }
    if (Objects.equals(userPlatform, UserPlatformEnum.APP.getCode())) {
      StpAppUtil.logoutByTokenValue(token);
    }
    return R.success();
  }
}
